<?php
class CF_Session_Element
{
	protected $_name;

	/**
	 * @var array
	 */
	protected $_defaultStorage = array(
		'data' => null,
		'modified' => null,
		'lifetime' => null,
		'hops' => null,
		'hopcount' => 0
	);
	
	/**
	 * @var array
	 */
	protected $_storage;
	
	/**
	 * 
	 * @param array $data
	 */
	public function __construct($name)
	{
		$this->_name = $name;
		
		if(!isset($_SESSION[CF_Session::ELEMENT_BASE_NAME][$name]))
			$_SESSION[CF_Session::ELEMENT_BASE_NAME][$name] = $this->_defaultStorage;
		
		$this->_storage = &$_SESSION[CF_Session::ELEMENT_BASE_NAME][$name];

		$this->_gc();
	}
	
	/**
	 * @return void
	 */
	protected function _gc()
	{
		if((null !== $this->_storage['lifetime'] 
				&& $this->_storage['lifetime'] + $this->_storage['modified'] < time())
			||(null !== $this->_storage['hops']
				&& $this->_storage['hopcount'] >= $this->_storage['hops'])
		){
			$this->_storage = null;
			return;
		}
		
		$this->_storage['modified'] = time();
		$this->_storage['hopcount'] = $this->_storage['hopcount'] + 1;
	}
	
	/**
	 * @return boolean
	 */
	public function has()
	{
		return !empty($this->_storage) && null !== $this->_storage['data'];	
	}
	
	/**
	 * @return mixed
	 */
	public function getData()
	{
		return $this->_storage['data'];
	}
	
	/**
	 * 
	 * @param mixed $data
	 * @return CF_Session_Element $this
	 */
	public function setData($data)
	{
		$this->_storage['data'] = $data;
		return $this;
	}
	
	/**
	 * @return int
	 */
	public function getModified()
	{
		return $this->_storage['modified'];
	}
	
	/**
	 * @return int
	 */
	public function getLifetime()
	{
		return $this->_storage['lifetime'];
	}
	
	/**
	 * 
	 * @param int $time
	 * @return CF_Session_Element $this
	 */
	public function setLifetime($time)
	{
		$this->_storage['lifetime'] = (int) $time;
		return $this;
	}
	
	/**
	 * @return int
	 */
	public function getHops()
	{
		return $this->_storage['hops'];
	}
	
	/**
	 * 
	 * @param int $hops
	 * @return CF_Session_Element $this
	 */
	public function setHops($hops)
	{
		$this->_storage['hops'] = (int) $hops;
		return $this;
	}
	
	/**
	 * @return int
	 */
	public function getHopCount() {
		return $this->_storage['hopcount'];
	}
	
	/**
	 * @return CF_Session_Element $this
	 */
	public function clear()
	{
		$this->_storage = $this->_defaultStorage;
		return $this;
	}
}